// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Matteo Perotti <mperotti@iis.ee.ethz.ch>
//         Basile Bougenot <bbougenot@student.ethz.ch>

#include "float_macros.h"
#include "vector_macros.h"

// Simple random test with similar values + 1 subnormal
void TEST_CASE1(void) {
  VSET(16, e16, m1);
  //               0.3501, -0.3289, -0.8853, -0.4082, -0.4346, -0.2659,  0.9316,
  //               0.5444, -0.0538,  0.7686,  0.8203, -0.8623,  0.3059,  0.0372,
  //               0.5337, -0.5815
  VLOAD_16(v2, 0x359a, 0xb543, 0xbb15, 0xb688, 0xb6f4, 0xb441, 0x3b74, 0x385b,
           0xaae4, 0x3a26, 0x3a90, 0xbae6, 0x34e5, 0x28c4, 0x3845, 0xb8a7);
  //              -0.8105,  0.5000, -0.8374, -0.8394,  0.3098,  0.1328, -0.2864,
  //              -0.4041, -0.1729,  0.0196,  0.2739,  0.8071, -0.1553,  0.2815,
  //              -0.9067, -0.2495
  VLOAD_16(v3, 0xba7c, 0x3800, 0xbab3, 0xbab7, 0x34f5, 0x3040, 0xb495, 0xb677,
           0xb188, 0x2502, 0x3462, 0x3a75, 0xb0f8, 0x3481, 0xbb41, 0xb3fc);
  //              -0.6558, -0.1006,  0.4558, -0.0784,  0.1539,  0.6748,  0.3347,
  //              -0.3416,  0.0614,  0.2289, -0.0829,  0.3838, -0.6348,  0.0843,
  //              -0.6890, -0.2598
  VLOAD_16(v1, 0xb93f, 0xae71, 0x374b, 0xad05, 0x30ed, 0x3966, 0x355b, 0xb577,
           0x2bdc, 0x3353, 0xad4f, 0x3624, 0xb914, 0x2d65, 0xb983, 0xb428);
  asm volatile("vfmadd.vv v1, v2, v3");
  //              -1.0400,  0.5332, -1.2412, -0.8071,  0.2429, -0.0466,  0.0254,
  //              -0.5898, -0.1761,  0.1954,  0.2058,  0.4761, -0.3496,  0.2847,
  //              -1.2744, -0.0984
  VCMP_U16(1, v1, 0xbc29, 0x3844, 0xbcf7, 0xba75, 0x33c6, 0xa9f7, 0x2684,
           0xb8b8, 0xb1a3, 0x3241, 0x3297, 0x379e, 0xb597, 0x348e, 0xbd19,
           0xae4d);

  VSET(16, e32, m1);
  //              -0.20637949, -0.63321692,  0.40850523,  0.58702314,
  //              -0.25534528, -0.22053087,  0.96057665,  0.85530519,
  //              0.74252450, -0.87175107, -0.00987994, -0.52556008, 0.26113954,
  //              -0.71307814,  0.78942811,  0.48685852
  VLOAD_32(v2, 0xbe535525, 0xbf221a81, 0x3ed12799, 0x3f164726, 0xbe82bc9e,
           0xbe61d2d8, 0x3f75e85a, 0x3f5af548, 0x3f3e1616, 0xbf5f2b14,
           0xbc21df78, 0xbf068b1b, 0x3e85b415, 0xbf368c4a, 0x3f4a17f6,
           0x3ef94585);
  //              -0.15712014,  0.83088422,  0.57509524,  0.85365236,
  //              -0.96695948,  0.71368766,  0.23281342, -0.67807233,
  //              0.79363507,  0.62817359,  0.37205252,  0.27726358,
  //              -0.85021532, -0.16634122, -0.58148408,  0.06963744
  VLOAD_32(v3, 0xbe20e41a, 0x3f54b4d4, 0x3f133971, 0x3f5a88f6, 0xbf778aa8,
           0x3f36b43c, 0x3e6e66a4, 0xbf2d9626, 0x3f4b2bab, 0x3f20cffc,
           0x3ebe7dab, 0x3e8df57e, 0xbf59a7b6, 0xbe2a555a, 0xbf14dc24,
           0x3d8e9e13);
  //              -0.63061494,  0.57643133,  0.08198822, -0.06029604,
  //              -0.84276563,  0.00681775,  0.30881208,  0.27571887,
  //              0.12349209,  0.29805747, -0.55497122, -0.52685922, 0.82809180,
  //              -0.83231467,  0.20959182,  0.15603130
  VLOAD_32(v1, 0xbf216ffb, 0x3f139101, 0x3da7e970, 0xbd76f8fa, 0xbf57bf7d,
           0x3bdf676d, 0x3e9e1c9e, 0x3e8d2b06, 0x3dfce96c, 0x3e989afd,
           0xbf0e1298, 0xbf06e03f, 0x3f53fdd3, 0xbf551293, 0x3e569f3d,
           0x3e1fc6ab);
  asm volatile("vfmadd.vv v1, v2, v3");
  //              -0.02697416,  0.46587816,  0.60858786,  0.81825721,
  //              -0.75176322,  0.71218413,  0.52945113, -0.44224855,
  //              0.88533098,  0.36834168,  0.37753561,  0.55415976,
  //              -0.63396782,  0.42716417, -0.41602641,  0.14560261
  VCMP_U32(2, v1, 0xbcdcf8e5, 0x3eee8795, 0x3f1bcc6a, 0x3f51794e, 0xbf40738e,
           0x3f3651b3, 0x3f078a1b, 0xbee26e67, 0x3f62a50d, 0x3ebc9748,
           0x3ec14c59, 0x3f0ddd6a, 0xbf224bb7, 0x3edab544, 0xbed5016a,
           0x3e1518d9);

  VSET(16, e64, m1);
  //               0.0308264568094008,  0.5865382185158325,  0.4543411851187289,
  //               0.0036656924511687, -0.3103508259554966,  0.9658177901158624,
  //               -0.3381631341283657, -0.2003719333831677, 0.8989532087589025,
  //               -0.8054516243685412,  0.8701363884969631,
  //               -0.3585976675814562,  0.4150155349314333,
  //               -0.6908185611649824,  0.8412555125501906, -0.3357469205066645
  VLOAD_64(v2, 0x3f9f90f87f644880, 0x3fe2c4ebcc4c25b4, 0x3fdd13ed0cd3e484,
           0x3f6e0783a63d2400, 0xbfd3dcc9b5f0fd10, 0x3feee7fab5ce29f4,
           0xbfd5a476fc72d40c, 0xbfc9a5c99a756020, 0x3fecc43985081eb2,
           0xbfe9c6427c2588e6, 0x3febd8284474eda0, 0xbfd6f343a1abca7c,
           0x3fda8f9d51773268, 0xbfe61b2f86f58c4a, 0x3feaeb90ae3f72fc,
           0xbfd57ce0a6d3c3f8);
  //               0.5881481456806663, -0.9882550591195853, -0.8483939717953815,
  //               -0.9684864200393222, -0.6743741213041285, 0.4372709704288931,
  //               -0.8339944484196176, -0.1519222509233684,
  //               -0.2540075520951832,  0.6661048539265222, 0.3013290199421905,
  //               -0.0367795249610035, -0.7178804756969177, 0.1577316726139908,
  //               -0.1242681642824526, -0.9006297759672148
  VLOAD_64(v3, 0x3fe2d21c0f5cd922, 0xbfef9fc912e0ce28, 0xbfeb260b1d5f82be,
           0xbfeefdd73b960c5a, 0xbfe594790988a396, 0x3fdbfc3f615edda8,
           0xbfeab01520204008, 0xbfc3723035a012c8, 0xbfd041a8e44be49c,
           0x3fe550bb206a47d8, 0x3fd348f9837f3238, 0xbfa2d4c411bd66e0,
           0xbfe6f8e079b1c412, 0x3fc4308d2bb5d1f0, 0xbfbfd009d586ef50,
           0xbfecd1f58932a7e4);
  //              -0.8344616273245185,  0.7077884806720691, -0.1882041492960900,
  //              -0.2751607560371576,  0.2338395078923734, -0.9938305657796487,
  //              -0.5345602642671559,  0.0887204597208056,  0.3045224871958914,
  //              -0.3946645040604191,  0.6818539464440989,  0.9719861381061521,
  //              -0.8471643748461517,  0.8077493118513845,  0.2789872574353331,
  //              0.7073875082318823
  VLOAD_64(v1, 0xbfeab3e8dee4061e, 0x3fe6a634071f1b28, 0xbfc81712d5195ee0,
           0xbfd19c3bdc149f5c, 0x3fcdee73f7748a88, 0xbfefcd75c2393d96,
           0xbfe11b1e209897fa, 0x3fb6b66250fca870, 0x3fd37d4be2d9c9a4,
           0xbfd9422ee8753844, 0x3fe5d1bf5e1407b4, 0x3fef1a82ac6a99b4,
           0xbfeb1bf876899dc0, 0x3fe9d91515b8951c, 0x3fd1daed5eabdf0c,
           0x3fe6a2eb20ae8e42);
  asm volatile("vfmadd.vv v1, v2, v3");
  //               0.5624246503668447, -0.5731100645801621, -0.9339028680308291,
  //               -0.9694950747455855, -0.7469464057195535,
  //               -0.5225882703620045, -0.6532258740745487,
  //               -0.1696993409682697,  0.0197439149088051, 0.9839880198025914,
  //               0.8946349503834604, -0.3853314870073767, -1.0694668518985466,
  //               -0.4002765447811873,  0.1104314039662806, -1.1381329534609521
  VCMP_U64(3, v1, 0x3fe1ff61faf9464f, 0xbfe256eaeb0c2af6, 0xbfede288447aa80f,
           0xbfef061a88f54aac, 0xbfe7e6fc260dc471, 0xbfe0b90b094f4be7,
           0xbfe4e739f2c1a370, 0xbfc5b8b53fce44b1, 0x3f9437bfb3503463,
           0x3fef7cd47196a75e, 0x3feca0d979b82d6d, 0xbfd8a94565b434f4,
           0xbff11c894610f720, 0xbfd99e21834c3aa4, 0x3fbc453b847c8ddf,
           0xbff235cae659d5ba);
};

// Simple random test with similar values + 1 subnormal (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE2(void) {
  VSET(16, e16, m1);
  //               0.3501, -0.3289, -0.8853, -0.4082, -0.4346, -0.2659,  0.9316,
  //               0.5444, -0.0538,  0.7686,  0.8203, -0.8623,  0.3059,  0.0372,
  //               0.5337, -0.5815
  VLOAD_16(v2, 0x359a, 0xb543, 0xbb15, 0xb688, 0xb6f4, 0xb441, 0x3b74, 0x385b,
           0xaae4, 0x3a26, 0x3a90, 0xbae6, 0x34e5, 0x28c4, 0x3845, 0xb8a7);
  //              -0.8105,  0.5000, -0.8374, -0.8394,  0.3098,  0.1328, -0.2864,
  //              -0.4041, -0.1729,  0.0196,  0.2739,  0.8071, -0.1553,  0.2815,
  //              -0.9067, -0.2495
  VLOAD_16(v3, 0xba7c, 0x3800, 0xbab3, 0xbab7, 0x34f5, 0x3040, 0xb495, 0xb677,
           0xb188, 0x2502, 0x3462, 0x3a75, 0xb0f8, 0x3481, 0xbb41, 0xb3fc);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.6558, -0.1006,  0.4558, -0.0784,  0.1539,  0.6748,  0.3347,
  //              -0.3416,  0.0614,  0.2289, -0.0829,  0.3838, -0.6348,  0.0843,
  //              -0.6890, -0.2598
  VLOAD_16(v1, 0xb93f, 0xae71, 0x374b, 0xad05, 0x30ed, 0x3966, 0x355b, 0xb577,
           0x2bdc, 0x3353, 0xad4f, 0x3624, 0xb914, 0x2d65, 0xb983, 0xb428);
  asm volatile("vfmadd.vv v1, v2, v3, v0.t");
  VCMP_U16(4, v1, 0xb93f, 0x3844, 0x374b, 0xba75, 0x30ed, 0xa9f7, 0x355b,
           0xb8b8, 0x2bdc, 0x3241, 0xad4f, 0x379e, 0xb914, 0x348e, 0xb983,
           0xae4d);

  VSET(16, e32, m1);
  //              -0.20637949, -0.63321692,  0.40850523,  0.58702314,
  //              -0.25534528, -0.22053087,  0.96057665,  0.85530519,
  //              0.74252450, -0.87175107, -0.00987994, -0.52556008, 0.26113954,
  //              -0.71307814,  0.78942811,  0.48685852
  VLOAD_32(v2, 0xbe535525, 0xbf221a81, 0x3ed12799, 0x3f164726, 0xbe82bc9e,
           0xbe61d2d8, 0x3f75e85a, 0x3f5af548, 0x3f3e1616, 0xbf5f2b14,
           0xbc21df78, 0xbf068b1b, 0x3e85b415, 0xbf368c4a, 0x3f4a17f6,
           0x3ef94585);
  //              -0.15712014,  0.83088422,  0.57509524,  0.85365236,
  //              -0.96695948,  0.71368766,  0.23281342, -0.67807233,
  //              0.79363507,  0.62817359,  0.37205252,  0.27726358,
  //              -0.85021532, -0.16634122, -0.58148408,  0.06963744
  VLOAD_32(v3, 0xbe20e41a, 0x3f54b4d4, 0x3f133971, 0x3f5a88f6, 0xbf778aa8,
           0x3f36b43c, 0x3e6e66a4, 0xbf2d9626, 0x3f4b2bab, 0x3f20cffc,
           0x3ebe7dab, 0x3e8df57e, 0xbf59a7b6, 0xbe2a555a, 0xbf14dc24,
           0x3d8e9e13);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.63061494,  0.57643133,  0.08198822, -0.06029604,
  //              -0.84276563,  0.00681775,  0.30881208,  0.27571887,
  //              0.12349209,  0.29805747, -0.55497122, -0.52685922, 0.82809180,
  //              -0.83231467,  0.20959182,  0.15603130
  VLOAD_32(v1, 0xbf216ffb, 0x3f139101, 0x3da7e970, 0xbd76f8fa, 0xbf57bf7d,
           0x3bdf676d, 0x3e9e1c9e, 0x3e8d2b06, 0x3dfce96c, 0x3e989afd,
           0xbf0e1298, 0xbf06e03f, 0x3f53fdd3, 0xbf551293, 0x3e569f3d,
           0x3e1fc6ab);
  asm volatile("vfmadd.vv v1, v2, v3, v0.t");
  VCMP_U32(5, v1, 0xbf216ffb, 0x3eee8795, 0x3da7e970, 0x3f51794e, 0xbf57bf7d,
           0x3f3651b3, 0x3e9e1c9e, 0xbee26e67, 0x3dfce96c, 0x3ebc9748,
           0xbf0e1298, 0x3f0ddd6a, 0x3f53fdd3, 0x3edab544, 0x3e569f3d,
           0x3e1518d9);

  VSET(16, e64, m1);
  //               0.0308264568094008,  0.5865382185158325,  0.4543411851187289,
  //               0.0036656924511687, -0.3103508259554966,  0.9658177901158624,
  //               -0.3381631341283657, -0.2003719333831677, 0.8989532087589025,
  //               -0.8054516243685412,  0.8701363884969631,
  //               -0.3585976675814562,  0.4150155349314333,
  //               -0.6908185611649824,  0.8412555125501906, -0.3357469205066645
  VLOAD_64(v2, 0x3f9f90f87f644880, 0x3fe2c4ebcc4c25b4, 0x3fdd13ed0cd3e484,
           0x3f6e0783a63d2400, 0xbfd3dcc9b5f0fd10, 0x3feee7fab5ce29f4,
           0xbfd5a476fc72d40c, 0xbfc9a5c99a756020, 0x3fecc43985081eb2,
           0xbfe9c6427c2588e6, 0x3febd8284474eda0, 0xbfd6f343a1abca7c,
           0x3fda8f9d51773268, 0xbfe61b2f86f58c4a, 0x3feaeb90ae3f72fc,
           0xbfd57ce0a6d3c3f8);
  //               0.5881481456806663, -0.9882550591195853, -0.8483939717953815,
  //               -0.9684864200393222, -0.6743741213041285, 0.4372709704288931,
  //               -0.8339944484196176, -0.1519222509233684,
  //               -0.2540075520951832,  0.6661048539265222, 0.3013290199421905,
  //               -0.0367795249610035, -0.7178804756969177, 0.1577316726139908,
  //               -0.1242681642824526, -0.9006297759672148
  VLOAD_64(v3, 0x3fe2d21c0f5cd922, 0xbfef9fc912e0ce28, 0xbfeb260b1d5f82be,
           0xbfeefdd73b960c5a, 0xbfe594790988a396, 0x3fdbfc3f615edda8,
           0xbfeab01520204008, 0xbfc3723035a012c8, 0xbfd041a8e44be49c,
           0x3fe550bb206a47d8, 0x3fd348f9837f3238, 0xbfa2d4c411bd66e0,
           0xbfe6f8e079b1c412, 0x3fc4308d2bb5d1f0, 0xbfbfd009d586ef50,
           0xbfecd1f58932a7e4);
  VLOAD_8(v0, 0xAA, 0xAA);
  //              -0.8344616273245185,  0.7077884806720691, -0.1882041492960900,
  //              -0.2751607560371576,  0.2338395078923734, -0.9938305657796487,
  //              -0.5345602642671559,  0.0887204597208056,  0.3045224871958914,
  //              -0.3946645040604191,  0.6818539464440989,  0.9719861381061521,
  //              -0.8471643748461517,  0.8077493118513845,  0.2789872574353331,
  //              0.7073875082318823
  VLOAD_64(v1, 0xbfeab3e8dee4061e, 0x3fe6a634071f1b28, 0xbfc81712d5195ee0,
           0xbfd19c3bdc149f5c, 0x3fcdee73f7748a88, 0xbfefcd75c2393d96,
           0xbfe11b1e209897fa, 0x3fb6b66250fca870, 0x3fd37d4be2d9c9a4,
           0xbfd9422ee8753844, 0x3fe5d1bf5e1407b4, 0x3fef1a82ac6a99b4,
           0xbfeb1bf876899dc0, 0x3fe9d91515b8951c, 0x3fd1daed5eabdf0c,
           0x3fe6a2eb20ae8e42);
  asm volatile("vfmadd.vv v1, v2, v3, v0.t");
  //               0.0000000000000000, -0.5731100645801621,  0.0000000000000000,
  //               -0.9694950747455855,  0.0000000000000000,
  //               -0.5225882703620045,  0.0000000000000000,
  //               -0.1696993409682697,  0.0000000000000000, 0.9839880198025914,
  //               0.0000000000000000, -0.3853314870073767,  0.0000000000000000,
  //               -0.4002765447811873,  0.0000000000000000, -1.1381329534609521
  VCMP_U64(6, v1, 0xbfeab3e8dee4061e, 0xbfe256eaeb0c2af6, 0xbfc81712d5195ee0,
           0xbfef061a88f54aac, 0x3fcdee73f7748a88, 0xbfe0b90b094f4be7,
           0xbfe11b1e209897fa, 0xbfc5b8b53fce44b1, 0x3fd37d4be2d9c9a4,
           0x3fef7cd47196a75e, 0x3fe5d1bf5e1407b4, 0xbfd8a94565b434f4,
           0xbfeb1bf876899dc0, 0xbfd99e21834c3aa4, 0x3fd1daed5eabdf0c,
           0xbff235cae659d5ba);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE3(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              0.6299
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x390a);
  //              -0.5352,  0.1115,  0.9541, -0.8857, -0.4143,  0.4045,  0.2949,
  //              -0.5479,  0.6733,  0.8965,  0.8882,  0.6294,  0.7568,  0.8735,
  //              -0.8569,  0.8271
  VLOAD_16(v2, 0xb848, 0x2f23, 0x3ba2, 0xbb16, 0xb6a1, 0x3679, 0x34b8, 0xb862,
           0x3963, 0x3b2c, 0x3b1b, 0x3909, 0x3a0e, 0x3afd, 0xbadb, 0x3a9e);
  //               0.2844,  0.1008,  0.3777,  0.9790, -0.8613,  0.4951,  0.4126,
  //               0.5518, -0.6680, -0.8340,  0.2094,  0.5884, -0.6509, -0.9360,
  //               -0.1609, -0.2527
  VLOAD_16(v1, 0x348d, 0x2e74, 0x360b, 0x3bd5, 0xbae4, 0x37ec, 0x369a, 0x386a,
           0xb958, 0xbaac, 0x32b3, 0x38b5, 0xb935, 0xbb7d, 0xb126, 0xb40b);
  asm volatile("vfmadd.vf v1, %[A], v2" ::[A] "f"(dscalar_16));
  //              -0.3560,  0.1750,  1.1924, -0.2690, -0.9570,  0.7163,  0.5547,
  //              -0.2002,  0.2527,  0.3711,  1.0195,  1.0000,  0.3469,  0.2842,
  //              -0.9580,  0.6680
  VCMP_U16(7, v1, 0xb5b2, 0x319a, 0x3cc5, 0xb44e, 0xbba8, 0x39bb, 0x3870,
           0xb269, 0x340b, 0x35f0, 0x3c15, 0x3c00, 0x358d, 0x348b, 0xbbab,
           0x3958);

  VSET(16, e32, m1);
  double dscalar_32;
  //                               0.80368215
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0x3f4dbe1d);
  //               0.13072050, -0.19741143,  0.09370349,  0.41049519,
  //               -0.69910282, -0.90573430,  0.86481184,  0.33341369,
  //               0.30657578, -0.90526944, -0.97891974, -0.50830764,
  //               0.79750061,  0.96885878,  0.48752418,  0.64305341
  VLOAD_32(v2, 0x3e05db98, 0xbe4a2639, 0x3dbfe79e, 0x3ed22c6d, 0xbf32f867,
           0xbf67de34, 0x3f5d644f, 0x3eaab533, 0x3e9cf780, 0xbf67bfbd,
           0xbf7a9a7c, 0xbf022073, 0x3f4c2900, 0x3f780721, 0x3ef99cc5,
           0x3f249f26);
  //              -0.61117887,  0.81778014, -0.46267223, -0.30897874,
  //              -0.84296966,  0.50125730,  0.96147668,  0.65802389,
  //              0.19629262, -0.73197508, -0.06948850, -0.60436314,
  //              -0.80817568,  0.72047287, -0.78180677, -0.40237895
  VLOAD_32(v1, 0xbf1c7638, 0x3f515a0a, 0xbeece360, 0xbe9e3276, 0xbf57ccdc,
           0x3f005266, 0x3f762356, 0x3f287441, 0x3e4900ef, 0xbf3b62b8,
           0xbd8e4ffc, 0xbf1ab78b, 0xbf4ee49a, 0x3f3870e9, 0xbf48247d,
           0xbece049d);
  asm volatile("vfmadd.vf v1, %[A], v2" ::[A] "f"(dscalar_32));
  //              -0.36047307,  0.45982391, -0.27813792,  0.16217449,
  //              -1.37658250, -0.50288272,  1.63753343,  0.86225569,
  //              0.46433264, -1.49354482, -1.03476644, -0.99402350, 0.14798427,
  //              1.54788995, -0.14079997,  0.31966865
  VCMP_U32(8, v1, 0xbeb88fed, 0x3eeb6e09, 0xbe8e6818, 0x3e261112, 0xbfb033db,
           0xbf00bced, 0x3fd19ab2, 0x3f5cbccb, 0x3eedbd02, 0xbfbf2c79,
           0xbf84733a, 0xbf7e7853, 0x3e17892e, 0x3fc62142, 0xbe102ddd,
           0x3ea3ab9c);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.5717861827636179
  BOX_DOUBLE_IN_DOUBLE(dscalar_64, 0x3fe24c128968c808);
  //               -0.0978999279373105, -0.8066508697961206, 0.1001298330116740,
  //               0.6183499729699258, -0.7091158569428311,  0.4713309006442494,
  //               -0.9363173157138223,  0.6720957973877764,
  //               -0.1684678230133414, -0.0206783343753454,
  //               -0.6941474840922310,  0.4809970389518419,
  //               -0.4671263490725479,  0.5176516826232249,
  //               -0.9714116214357187,  0.0212574845134876
  VLOAD_64(v2, 0xbfb90ff83cc58160, 0xbfe9d0157c220eae, 0x3fb9a21bd6239ad0,
           0x3fe3c985e1ec6d14, 0xbfe6b113bcd49f88, 0x3fde2a4914f71f28,
           0xbfedf64fbb356b82, 0x3fe581cf0bb1e7c4, 0xbfc5905a8722a398,
           0xbf952cb38782ee00, 0xbfe63674c8d8dba6, 0x3fdec8a7cdf1580c,
           0xbfdde565ea17744c, 0x3fe0909a42f2c184, 0xbfef15cdd320a9f0,
           0x3f95c485a31f6440);
  //               -0.8599787754583945, -0.8609648323347547,
  //               -0.5642848553711928,  0.8958493001041692, 0.3661374487395561,
  //               0.1017901385891375,  0.2298954297904690, -0.4970717320718749,
  //               -0.5860844501192310, -0.6581386742527398,
  //               -0.8379133193505066, -0.6497652150347000,
  //               -0.4444119628309799, -0.8810041425660891, 0.4421772814931029,
  //               0.0606105644967410
  VLOAD_64(v1, 0xbfeb84f2357b2242, 0xbfeb8d061ebc48de, 0xbfe20e9f1cee50cc,
           0x3fecaacc26c2f0d0, 0x3fd76ecbc40b5864, 0x3fba0eeb244baff0,
           0x3fcd6d36a4399740, 0xbfdfd005f440f21c, 0xbfe2c1342d3e9986,
           0xbfe50f78d644befe, 0xbfead02f97efc88a, 0xbfe4cae06b94e0d2,
           0xbfdc713edf93dac0, 0xbfec312f997ec7ac, 0x3fdc4ca1f0c30314,
           0x3faf0859109c77c0);
  asm volatile("vfmadd.vf v1, %[A], v2" ::[A] "f"(dscalar_64));
  //              -0.5896239092143964, -1.2989386647705283, -0.2225204504323405,
  //              1.1305842246079476, -0.4997635227612305,  0.5295330954311120,
  //              -0.8048662854791286,  0.3878770491466992, -0.5035828135241305,
  //              -0.3969929346554276, -1.1732547424504496,  0.1094702669545694,
  //              -0.7212349688741608,  0.0139056869464266, -0.7185807615459836,
  //              0.0559137678222272
  VCMP_U64(9, v1, 0xbfe2de32f5e07f06, 0xbff4c873e8cb3071, 0xbfcc7b8cd4a627de,
           0x3ff216df7be108d1, 0xbfdffc20247f9130, 0x3fe0f1ef63e0d73b,
           0xbfe9c176f0b925be, 0x3fd8d2fa423d0f48, 0xbfe01d59b45d3de9,
           0xbfd968550dc5a3de, 0xbff2c5a6c3cb39b0, 0x3fbc063e50744ab8,
           0xbfe7145b5b8179a4, 0x3f8c7a95b54e78da, 0xbfe6fe9d14cbfe26,
           0x3faca0bab8629cdd);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE4(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              0.6299
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x390a);
  //               -0.5352,  0.1115,  0.9541, -0.8857, -0.4143,  0.4045, 0.2949,
  //               -0.5479,  0.6733,  0.8965,  0.8882,  0.6294,  0.7568, 0.8735,
  //               -0.8569,  0.8271
  VLOAD_16(v2, 0xb848, 0x2f23, 0x3ba2, 0xbb16, 0xb6a1, 0x3679, 0x34b8, 0xb862,
           0x3963, 0x3b2c, 0x3b1b, 0x3909, 0x3a0e, 0x3afd, 0xbadb, 0x3a9e);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                0.2844,  0.1008,  0.3777,  0.9790, -0.8613,  0.4951, 0.4126,
  //                0.5518, -0.6680, -0.8340,  0.2094,  0.5884, -0.6509,
  //                -0.9360, -0.1609, -0.2527
  VLOAD_16(v1, 0x348d, 0x2e74, 0x360b, 0x3bd5, 0xbae4, 0x37ec, 0x369a, 0x386a,
           0xb958, 0xbaac, 0x32b3, 0x38b5, 0xb935, 0xbb7d, 0xb126, 0xb40b);
  asm volatile("vfmadd.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_16));
  VCMP_U16(10, v1, 0x348d, 0x319a, 0x360b, 0xb44e, 0xbae4, 0x39bb, 0x369a,
           0xb269, 0xb958, 0x35f0, 0x32b3, 0x3c00, 0xb935, 0x348b, 0xb126,
           0x3958);

  VSET(16, e32, m1);
  double dscalar_32;
  //                               0.80368215
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0x3f4dbe1d);
  //                0.13072050, -0.19741143,  0.09370349,  0.41049519,
  //                -0.69910282, -0.90573430,  0.86481184,  0.33341369,
  //                0.30657578, -0.90526944, -0.97891974, -0.50830764,
  //                0.79750061,  0.96885878,  0.48752418,  0.64305341
  VLOAD_32(v2, 0x3e05db98, 0xbe4a2639, 0x3dbfe79e, 0x3ed22c6d, 0xbf32f867,
           0xbf67de34, 0x3f5d644f, 0x3eaab533, 0x3e9cf780, 0xbf67bfbd,
           0xbf7a9a7c, 0xbf022073, 0x3f4c2900, 0x3f780721, 0x3ef99cc5,
           0x3f249f26);
  VLOAD_8(v0, 0xAA, 0xAA);
  //               -0.61117887,  0.81778014, -0.46267223, -0.30897874,
  //               -0.84296966,  0.50125730,  0.96147668,  0.65802389,
  //               0.19629262, -0.73197508, -0.06948850, -0.60436314,
  //               -0.80817568,  0.72047287, -0.78180677, -0.40237895
  VLOAD_32(v1, 0xbf1c7638, 0x3f515a0a, 0xbeece360, 0xbe9e3276, 0xbf57ccdc,
           0x3f005266, 0x3f762356, 0x3f287441, 0x3e4900ef, 0xbf3b62b8,
           0xbd8e4ffc, 0xbf1ab78b, 0xbf4ee49a, 0x3f3870e9, 0xbf48247d,
           0xbece049d);
  asm volatile("vfmadd.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_32));
  VCMP_U32(11, v1, 0xbf1c7638, 0x3eeb6e09, 0xbeece360, 0x3e261112, 0xbf57ccdc,
           0xbf00bced, 0x3f762356, 0x3f5cbccb, 0x3e4900ef, 0xbfbf2c79,
           0xbd8e4ffc, 0xbf7e7853, 0xbf4ee49a, 0x3fc62142, 0xbf48247d,
           0x3ea3ab9c);

  VSET(16, e64, m1);
  double dscalar_64;
  //                                0.5717861827636179
  BOX_DOUBLE_IN_DOUBLE(dscalar_64, 0x3fe24c128968c808);
  //                -0.0978999279373105, -0.8066508697961206,
  //                0.1001298330116740,  0.6183499729699258,
  //                -0.7091158569428311,  0.4713309006442494,
  //                -0.9363173157138223,  0.6720957973877764,
  //                -0.1684678230133414, -0.0206783343753454,
  //                -0.6941474840922310,  0.4809970389518419,
  //                -0.4671263490725479,  0.5176516826232249,
  //                -0.9714116214357187,  0.0212574845134876
  VLOAD_64(v2, 0xbfb90ff83cc58160, 0xbfe9d0157c220eae, 0x3fb9a21bd6239ad0,
           0x3fe3c985e1ec6d14, 0xbfe6b113bcd49f88, 0x3fde2a4914f71f28,
           0xbfedf64fbb356b82, 0x3fe581cf0bb1e7c4, 0xbfc5905a8722a398,
           0xbf952cb38782ee00, 0xbfe63674c8d8dba6, 0x3fdec8a7cdf1580c,
           0xbfdde565ea17744c, 0x3fe0909a42f2c184, 0xbfef15cdd320a9f0,
           0x3f95c485a31f6440);
  VLOAD_8(v0, 0xAA, 0xAA);
  //                -0.8599787754583945, -0.8609648323347547,
  //                -0.5642848553711928,  0.8958493001041692,
  //                0.3661374487395561,  0.1017901385891375, 0.2298954297904690,
  //                -0.4970717320718749, -0.5860844501192310,
  //                -0.6581386742527398, -0.8379133193505066,
  //                -0.6497652150347000, -0.4444119628309799,
  //                -0.8810041425660891,  0.4421772814931029, 0.0606105644967410
  VLOAD_64(v1, 0xbfeb84f2357b2242, 0xbfeb8d061ebc48de, 0xbfe20e9f1cee50cc,
           0x3fecaacc26c2f0d0, 0x3fd76ecbc40b5864, 0x3fba0eeb244baff0,
           0x3fcd6d36a4399740, 0xbfdfd005f440f21c, 0xbfe2c1342d3e9986,
           0xbfe50f78d644befe, 0xbfead02f97efc88a, 0xbfe4cae06b94e0d2,
           0xbfdc713edf93dac0, 0xbfec312f997ec7ac, 0x3fdc4ca1f0c30314,
           0x3faf0859109c77c0);
  asm volatile("vfmadd.vf v1, %[A], v2, v0.t" ::[A] "f"(dscalar_64));
  VCMP_U64(12, v1, 0xbfeb84f2357b2242, 0xbff4c873e8cb3071, 0xbfe20e9f1cee50cc,
           0x3ff216df7be108d1, 0x3fd76ecbc40b5864, 0x3fe0f1ef63e0d73b,
           0x3fcd6d36a4399740, 0x3fd8d2fa423d0f48, 0xbfe2c1342d3e9986,
           0xbfd968550dc5a3de, 0xbfead02f97efc88a, 0x3fbc063e50744ab8,
           0xbfdc713edf93dac0, 0x3f8c7a95b54e78da, 0x3fdc4ca1f0c30314,
           0x3faca0bab8629cdd);
};

int main(void) {
  enable_vec();
  enable_fp();

  TEST_CASE1();
  TEST_CASE2();
  TEST_CASE3();
  TEST_CASE4();

  EXIT_CHECK();
}
